package com.zhijian.warehouse.manage.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.format.FastDateFormat;
import com.zhijian.util.AssertUtil;
import com.zhijian.util.BeanUtil;
import com.zhijian.util.page.Page;
import com.zhijian.warehouse.manage.dao.AccessProductRecordMapper;
import com.zhijian.warehouse.manage.entity.export.AccessOverdueRecordExport;
import com.zhijian.warehouse.manage.entity.export.AccessProductRecordExport;
import com.zhijian.warehouse.manage.entity.po.AccessProductRecord;
import com.zhijian.warehouse.manage.entity.po.Product;
import com.zhijian.warehouse.manage.entity.vo.request.*;
import com.zhijian.warehouse.manage.entity.vo.response.AccessProductRecordVo;
import com.zhijian.warehouse.manage.enums.CodingEnum;
import com.zhijian.warehouse.manage.enums.ProductEnum;
import com.zhijian.warehouse.manage.service.AccessProductRecordService;
import com.zhijian.warehouse.manage.service.ProductService;
import com.zhijian.warehouse.manage.util.AssertCommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 仪器领用归记录业务处理层
 *
 * @author auto
 * @version: 1.0
 * @date 2024-10-28 17:42:45
 */
@Slf4j
@Service
public class AccessProductRecordServiceImpl implements AccessProductRecordService {

    @Autowired
    private AccessProductRecordMapper mapper;

    @Autowired
    private ProductService productService;

    @Override
    public AccessProductRecord selectById(Long id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public AccessProductRecordVo selectVoById(Long id) {
        return mapper.selectVoById(id);
    }

    @Override
    public void deleteById(Long id) {
        mapper.deleteByPrimaryKey(id);
    }

    @Override
    public void deleteByIdList(List<Long> idList) {
        if (CollectionUtil.isEmpty(idList)) {
            return;
        }
        mapper.deleteByIdList(idList);
    }

    @Override
    public Long insert(AccessProductRecord accessProductRecord) {
        Date now = new Date();
        accessProductRecord.setCreateTime(now);
        accessProductRecord.setUpdateTime(now);
        return mapper.insert(accessProductRecord) > 0 ? accessProductRecord.getId() : 0L;
    }

    @Override
    public Long insertSelective(AccessProductRecord accessProductRecord) {
        Date now = new Date();
        accessProductRecord.setCreateTime(now);
        accessProductRecord.setUpdateTime(now);
        return mapper.insertSelective(accessProductRecord) > 0 ? accessProductRecord.getId() : 0L;
    }

    @Override
    public boolean update(AccessProductRecord accessProductRecord) {
        Date now = new Date();
        accessProductRecord.setUpdateTime(now);
        return mapper.updateByPrimaryKey(accessProductRecord) != 0;
    }

    @Override
    public boolean updateByPrimaryKeySelective(AccessProductRecord record) {
        Date now = new Date();
        record.setUpdateTime(now);
        return mapper.updateByPrimaryKeySelective(record) != 0;
    }

    @Override
    @Transactional
    public boolean save(AccessProductRecordSaveOrUpdateVo saveOrUpdateVo) {
        AssertCommonUtil.check(BeanUtil.isEmpty(saveOrUpdateVo.getProducts()), "领用或者归还产品不能为空");
        for (AppAccessProductRecordVo product : saveOrUpdateVo.getProducts()) {
            AccessProductRecord accessProductRecord = new AccessProductRecord();
            BeanUtils.copyProperties(saveOrUpdateVo, accessProductRecord);
            accessProductRecord.setDrawDay(product.getDrawDay());
            accessProductRecord.setProductId(product.getProductId());
            if (accessProductRecord.getDrawDay() == null) {
                Product productVo = productService.selectById(product.getProductId());
                if (productVo == null || productVo.getLimitDay() == null) {
                    accessProductRecord.setDrawDay(1);
                } else {
                    accessProductRecord.setDrawDay(productVo.getLimitDay());
                }
            }
            String nextNumber = createNextNumber();
            String time = DateUtil.formatDateTime(new Date());
            if (saveOrUpdateVo.getType() == 1) {
                accessProductRecord.setDrawNumber(nextNumber);
                accessProductRecord.setDrawTime(time);
                String formattedNewPlanBackTime = calculateNewPlanBackTime(product.getDrawDay(), DateUtil.formatDateTime(new Date()));
                accessProductRecord.setPlanBackTime(formattedNewPlanBackTime);
                this.insertSelective(accessProductRecord);
            } else {
                AccessProductRecordVo accessProductRecordVo =
                        selectOne(AccessProductRecordSearchVo.builder().productId(product.getProductId()).build());
                String substring = nextNumber.substring(4);
                String backNumber = String.format("%s%s", CodingEnum.PREFIX.GH.value, substring);
                if (BeanUtil.isEmpty(accessProductRecordVo)) {
                    //去掉前四位,保留后面的数字
                    accessProductRecord.setBackNumber(backNumber);
                    accessProductRecord.setBackTime(time);
                    this.insertSelective(accessProductRecord); //没有领用单 只有归还单
                } else {
                    this.updateByPrimaryKeySelective(AccessProductRecord.builder()
                            .id(accessProductRecordVo.getId())
                            .backTime(time)
                            .backUserId(saveOrUpdateVo.getBackUserId())
                            .type(saveOrUpdateVo.getType())
                            .backNumber(backNumber)
                            .msg(saveOrUpdateVo.getMsg())
                            .build());
                }
            }
            //修改产品状态
            productService.updateByPrimaryKeySelective(Product.builder()
                    .id(product.getProductId())
                    .useStatus(saveOrUpdateVo.getType() == 1
                            ? Byte.valueOf(String.valueOf(ProductEnum.UseStatusEnum.YES.getCode()))
                            : Byte.valueOf(String.valueOf(ProductEnum.UseStatusEnum.NO.getCode())))
                    .build());
        }

        return true;
    }

    @Override
    public boolean modify(AccessProductRecordSaveOrUpdateVo saveOrUpdateVo) {
        AccessProductRecord old = this.selectById(saveOrUpdateVo.getId());
        AssertCommonUtil.notNull(old, "此数据不存在或者已被删除");
        AccessProductRecord accessProductRecord = new AccessProductRecord();
        BeanUtils.copyProperties(saveOrUpdateVo, accessProductRecord);
        return this.updateByPrimaryKeySelective(accessProductRecord);
    }

    @Override
    public AccessProductRecordVo selectOne(AccessProductRecordSearchVo accessProductRecordSearchVo) {
        return mapper.selectOne(accessProductRecordSearchVo);
    }

    @Override
    public Integer count(AccessProductRecordSearchVo accessProductRecordSearchVo) {
        return mapper.count(accessProductRecordSearchVo);
    }

    @Override
    public Integer countDrawBack(AccessProductRecordSearchVo accessProductRecordSearchVo) {
        return mapper.countDrawBack(accessProductRecordSearchVo);
    }

    @Override
    public List<AccessProductRecordVo> selectList(AccessProductRecordSearchVo accessProductRecordSearchVo) {
        return mapper.selectList(accessProductRecordSearchVo);
    }

    @Override
    public List<AccessProductRecordExport> selectExportList(AccessProductRecordSearchVo accessProductRecordSearchVo) {
        return mapper.selectExportList(accessProductRecordSearchVo);
    }

    @Override
    public Page<AccessProductRecordVo> selectPage(AccessProductRecordSearchVo accessProductRecordSearchVo) {
        AssertCommonUtil.check(Objects.isNull(accessProductRecordSearchVo.getPageNum()) || Objects.isNull(accessProductRecordSearchVo.getPageSize()), "分页参数不能为空");
        //先直接查总数
        int count = count(accessProductRecordSearchVo);
        //分页
        Page<AccessProductRecordVo> page = new Page<>(true, count, accessProductRecordSearchVo.getPageNum(), accessProductRecordSearchVo.getPageSize());
        accessProductRecordSearchVo.setStartIndex(page.getStartIndex());
        page.setPage(true);
        page.setTotalCount(count);
        List<AccessProductRecordVo> responseVos = this.selectList(accessProductRecordSearchVo);
        page.setData(responseVos);
        return page;
    }

    @Override
    public boolean insertBatch(List<AccessProductRecord> entities) {
        return CollectionUtil.isNotEmpty(entities) && mapper.insertBatch(entities) > 0;
    }

    @Override
    public String selectMaxNumber() {
        return mapper.selectMaxNumberByDay(DateUtil.formatDate(new Date()));
    }

    @Override
    public String createNextNumber() {
        String maxCode = this.selectMaxNumber();
        if (StringUtils.isBlank(maxCode)) {
            return String.format("%s-%s-001", CodingEnum.PREFIX.LY.value, DateUtil.format(new Date(), FastDateFormat.getInstance("yyyyMMdd")));
        }
        String[] maxCodeArray = maxCode.split("-");
        Integer i = Integer.valueOf(maxCodeArray[maxCodeArray.length - 1]);
        i++;
        return String.format("%s-%s-%s", CodingEnum.PREFIX.LY.value, DateUtil.format(new Date(), FastDateFormat.getInstance("yyyyMMdd")), String.format("%03d", i));
    }


    private Integer countOverdue(AccessProductRecordSearchVo accessProductRecordSearchVo) {
        return mapper.countOverdue(accessProductRecordSearchVo);
    }


    private List<AccessProductRecordVo> selectOverdueList(AccessProductRecordSearchVo accessProductRecordSearchVo) {
        return mapper.selectOverdueList(accessProductRecordSearchVo);
    }

    @Override
    public List<AccessOverdueRecordExport> selectOverdueExportList(AccessProductRecordSearchVo accessProductRecordSearchVo) {
        return mapper.selectOverdueExportList(accessProductRecordSearchVo);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Page<AccessProductRecordVo> selectOverdueByCondition(AccessProductRecordSearchVo param) {
        AssertCommonUtil.check(Objects.isNull(param.getPageNum()) || Objects.isNull(param.getPageSize()), "分页参数不能为空");
        //先直接查总数
        int count = countOverdue(param);
        //分页
        Page<AccessProductRecordVo> page = new Page<>(true, count, param.getPageNum(), param.getPageSize());
        param.setStartIndex(page.getStartIndex());
        page.setPage(true);
        page.setTotalCount(count);
        List<AccessProductRecordVo> responseVos = this.selectOverdueList(param);
        page.setData(responseVos);
        return page;
    }


    @Override
    public boolean back(AccessProductBackVo param) {
        for (Long id : param.getIds()) {
            AccessProductRecord accessProductRecord = selectById(id);
            if (BeanUtil.isNotEmpty(accessProductRecord)) {
                String nextNumber = createNextNumber();
                String substring = nextNumber.substring(4);
                String backNumber = String.format("%s-%s", CodingEnum.PREFIX.GH.value, substring);
                this.updateByPrimaryKeySelective(AccessProductRecord.builder()
                        .id(id)
                        .backTime(DateUtil.formatDateTime(new Date()))
                        .backUserId(accessProductRecord.getDrawUserId())
                        .backNumber(backNumber)
                        .type(2)
                        .build());
                //产品在库
                productService.updateByPrimaryKeySelective(Product.builder()
                        .id(accessProductRecord.getProductId())
                        .useStatus(Byte.valueOf(String.valueOf(ProductEnum.UseStatusEnum.NO.getCode())))
                        .build());
            }
        }
        return true;
    }

    @Override
    public boolean extend(AccessProductExtendVo param) {
        AssertUtil.check(BeanUtil.isEmpty(param.getExtendDay()), "延长天数不能为空");
        AssertUtil.check(BeanUtil.isEmpty(param.getId()), "领用记录id不能为空");
        AccessProductRecord accessProductRecord = selectById(param.getId());
        AssertCommonUtil.notNull(accessProductRecord, "此数据不存在或者已被删除");
        String formattedNewPlanBackTime = calculateNewPlanBackTime(param.getExtendDay(), accessProductRecord.getPlanBackTime());
        return this.updateByPrimaryKeySelective(AccessProductRecord.builder()
                .id(accessProductRecord.getId())
                .extendDay(accessProductRecord.getExtendDay() == null ? param.getExtendDay() : accessProductRecord.getExtendDay() + param.getExtendDay())
                .planBackTime(formattedNewPlanBackTime)
                .build());
    }

    private String calculateNewPlanBackTime(Integer extendDay, String planBackTime) {
        // 定义时间格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 将原计划返回时间转换为LocalDateTime
        LocalDateTime originalTime = LocalDateTime.parse(planBackTime, formatter);
        // 将扩展天数添加到原计划返回时间
        LocalDateTime newPlanBackTime = originalTime.plusDays(extendDay);
        // 将新的计划返回时间格式化为字符串
        return newPlanBackTime.format(formatter);
    }
}
